﻿#include "battery_top_invade.h"


// 使用 utf8 编码
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

// 动力电池顶部异物检测

/// <summary>
/// 
/// </summary>
battery_top_invade::battery_top_invade()
{
	m_pTopDet = nullptr;
	m_pTopRectDefect = nullptr;
	m_pTopRectClass = nullptr;
}


/// <summary>
/// 
/// </summary>
battery_top_invade::~battery_top_invade()
{
	if (m_pTopDet != nullptr)
	{
		m_pTopDet->Release();
		m_pTopDet = nullptr;
	}
	if (m_pTopRectDefect != nullptr)
	{
		m_pTopRectDefect->Release();
		m_pTopRectDefect = nullptr;
	}
	if (m_pTopRectClass != nullptr)
	{
		m_pTopRectClass->Release();
		m_pTopRectClass = nullptr;
	}
	
}


/// <summary>
/// 
/// </summary>
/// <returns></returns>
void battery_top_invade::init()
{
	m_pTopDet = CreateDetObj(m_strTopDetModelPath);
	m_pTopRectDefect = CreateDetObj(m_strTopRectDefectModelPath);
	m_pTopRectClass = CreateClsObj(m_strTopRectClassModelPath);
}


/// <summary>
/// 
/// </summary>
/// <param name="pData"></param>
void battery_top_invade::execute(QSharedPointer<IMG_DATA> pData, int nBuffersize)
{
	IMG_DATA data = *pData;
	data.image = urlToPixmap(data.strUrl);
	saveImage(data);

	cv::Mat image = QImage2cvMat(data.image);
	int nDispId = data.nDispId;

	if (!image.data || m_pTopDet == nullptr)
	{
		return;
	}

	std::vector<DetectResult> results;
	m_pTopDet->Evaluate(image, results);
	// 保存图片
	saveImage(image, "电池顶(定位)", data, results.size());

	for (int i = 0; i < results.size(); i++)
	{
		DetectResult res = results[i];
		cv::Rect rect = res.box;
		rect &= cv::Rect(0, 0, image.cols, image.rows);//求交集
		cv::Mat image_roi = image(rect);

		// 仅检测序号为 0 的目标
		if (res.classes != 0)
		{
			continue;
		}

		std::vector<DetectResult> def_results;
		std::vector<DetectResult> def_results_base;
		if (m_pTopRectDefect != nullptr)
		{
			m_pTopRectDefect->Evaluate(image_roi, def_results_base);
		}
		
		// 将检测出来超过一定宽高的目标，加入结果列表
		for (int i = 0; i < def_results_base.size(); i++)
		{
			DetectResult res = def_results_base[i];
			if (res.box.width > 100 &&
				res.box.height > 100 
				)
			{
				cv::Rect rect = res.box;
				rect &= cv::Rect(0, 0, image_roi.cols, image_roi.rows);//求交集
				cv::Mat roi = image_roi(rect);


				
				if (m_pTopRectClass != nullptr)
				{
					std::vector<int> rstClassList;
					std::vector<float> rstProbList;

					std::vector<cv::Mat> srcImgs;
					srcImgs.push_back(roi);
					m_pTopRectClass->Evaluate(srcImgs, rstClassList, rstProbList);

					// 0 表示 OK 类别，1 表示 NG 类别
					if (rstClassList[0] == 1)
					{
						def_results.push_back(res);
					}
					saveImage(roi, "顶部异物(裁剪)", data, rstClassList[0]);

				}
			}
		}


		saveImage(image_roi, "电池顶部异物", data, def_results.size());

		// 如果没检测到破损，则不发布破损相关的数据
		if (def_results.size() != 0)
		{
			// 返回结果到 kafka 
			_tagResults tagResults;
			tagResults.setImageData(data);
			tagResults.setResults("顶部异物", def_results, res.box.x, res.box.y);
			tagResults.setVersion(m_strTopRectDefectModelPath);

			QString strResultTopc = data.strTopicName + suffix_2;
			QString strResultData = tagResults.toJSon();

			pushKafka(strResultTopc, strResultData, data.strStationId);
		}


		QPainter painter(&data.image);

		if (def_results.size() == 0)
		{
			painter.setBrush(QBrush(QColor(0, 255, 0, 50)));
			QPen pen(QColor(0, 255, 0));
			pen.setWidth(5);
			painter.setPen(pen);
		}
		else
		{
			painter.setBrush(QBrush(QColor(255, 0, 0, 50)));
			QPen pen(Qt::red);
			pen.setWidth(5);
			painter.setPen(pen);
		}

		cv::Point point = getCenterPoint(rect);
		painter.drawRect(rect.tl().x, rect.tl().y, rect.width, rect.height);

		emit updateShow(data.nDispId, data.image, nBuffersize);

	}



	// 返回结果到 kafka 
	_tagResults tagResults;
	tagResults.setImageData(data);
	tagResults.setResults("电池顶部", results);
	tagResults.setVersion(m_strTopDetModelPath);

	QString strResultTopc = data.strTopicName + suffix_1;
	QString strResultData = tagResults.toJSon();

	pushKafka(strResultTopc, strResultData, data.strStationId);
}
